home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / util / moni / Scout-src.lha / source / objects / scout_interrupts.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-17  |  21.5 KB  |  574 lines

  1. /**
  2.  * Scout - The Amiga System Monitor
  3.  *
  4.  *------------------------------------------------------------------
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * You must not use this source code to gain profit of any kind!
  21.  *
  22.  *------------------------------------------------------------------
  23.  *
  24.  * @author Andreas Gelhausen
  25.  * @author Richard Körber <rkoerber@gmx.de>
  26.  */
  27.  
  28. #include "system_headers.h"
  29.  
  30. struct InterruptsCallbackUserData {
  31.     APTR ud_Tree;
  32.     ULONG ud_Count;
  33.     UBYTE *ud_FindMe;
  34.     struct Interrupt *ud_FoundThis;
  35. };
  36.  
  37. static UBYTE *intTypeShort[] = {
  38.     "1 / Serial Out",
  39.     "1 / Disk Block",
  40.     "1 / SoftInt",
  41.     "2 / INT2/CIAA",
  42.     "3 / Copper",
  43.     "3 / Vertical Blank",
  44.     "3 / Blitter",
  45.     "4 / Audio 0",
  46.     "4 / Audio 1",
  47.     "4 / Audio 2",
  48.     "4 / Audio 3",
  49.     "5 / Serial In",
  50.     "5 / Disk Sync",
  51.     "6 / INT6/CIAB",
  52.     "6 / INTEN",
  53.     "7 / NMI"
  54. };
  55.  
  56. static __asm __saveds LONG inttree_confunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_ConstructMessage *msg, register __a0 struct Hook *hook)
  57. {
  58.     return AllocListEntry(msg->MemPool, msg->UserData, sizeof(struct InterruptEntry));
  59. }
  60.  
  61. MakeHook(inttree_conhook, inttree_confunc);
  62.  
  63. static __asm __saveds LONG inttree_desfunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_ConstructMessage *msg, register __a0 struct Hook *hook)
  64. {
  65.     FreeListEntry(msg->MemPool, &msg->UserData);
  66.  
  67.     return 0;
  68. }
  69.  
  70. MakeHook(inttree_deshook, inttree_desfunc);
  71.  
  72. static __asm __saveds LONG inttree_dspfunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_DisplayMessage *msg, register __a0 struct Hook *hook)
  73. {
  74.     static UBYTE *empty = "\0";
  75.  
  76.     if (msg->TreeNode != NULL) {
  77.         struct InterruptEntry *ie = msg->TreeNode->tn_User;
  78.  
  79.         if (stricmp(ie->ie_Type, "HANDLER") == 0) {
  80.             msg->Array[0] = ie->ie_Address;
  81.             msg->Array[1] = ie->ie_Number;
  82.             msg->Array[2] = ie->ie_Name;
  83.             msg->Array[3] = ie->ie_Kind;
  84.             msg->Array[4] = ie->ie_Pri;
  85.             msg->Array[5] = ie->ie_Data;
  86.             msg->Array[6] = ie->ie_Code;
  87.         } else if (stricmp(ie->ie_Type, "SERVER_LIST") == 0) {
  88.             msg->Array[0] = ie->ie_Address;
  89.             msg->Array[1] = ie->ie_Number;
  90.             msg->Array[2] = empty;
  91.             msg->Array[3] = ie->ie_Kind;
  92.             msg->Array[4] = ie->ie_Pri;
  93.             msg->Array[5] = ie->ie_Data;
  94.             msg->Array[6] = ie->ie_Code;
  95.         } else if (stricmp(ie->ie_Type, "SERVER_NODE") == 0) {
  96.             msg->Array[0] = ie->ie_Address;
  97.             msg->Array[1] = ie->ie_Number;
  98.             msg->Array[2] = ie->ie_Name;
  99.             msg->Array[3] = empty;
  100.             msg->Array[4] = ie->ie_Pri;
  101.             msg->Array[5] = ie->ie_Data;
  102.             msg->Array[6] = ie->ie_Code;
  103.         }
  104.     } else {
  105.         msg->Array[0] = "Address";
  106.         msg->Array[1] = "IPL / Interrupt";
  107.         msg->Array[2] = "ln_Name";
  108.         msg->Array[3] = "Type";
  109.         msg->Array[4] = "ln_Pri";
  110.         msg->Array[5] = "is_Data";
  111.         msg->Array[6] = "is_Code";
  112.         msg->Preparse[0] = MUIX_B;
  113.         msg->Preparse[1] = MUIX_B;
  114.         msg->Preparse[2] = MUIX_B;
  115.         msg->Preparse[3] = MUIX_B;
  116.         msg->Preparse[4] = MUIX_B;
  117.         msg->Preparse[5] = MUIX_B;
  118.         msg->Preparse[6] = MUIX_B;
  119.     }
  120.  
  121.     return 0;
  122. }
  123.  
  124. MakeHook(inttree_dsphook, inttree_dspfunc);
  125.  
  126. static __asm __saveds LONG inttree_findfunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_FindUserDataMessage *msg, register __a0 struct Hook *hook)
  127. {
  128.     struct InterruptEntry *ie;
  129.  
  130.     ie = (struct InterruptEntry *)msg->UserData;
  131.  
  132.     if (ie) {
  133.         return stricmp((UBYTE *)msg->User, ie->ie_RealNumber);
  134.     } else {
  135.         return ~0;
  136.     }
  137. }
  138.  
  139. MakeHook(inttree_findhook, inttree_findfunc);
  140.  
  141. static void ReceiveList( void (* callback)( struct InterruptEntry *ie, void *userData ),
  142.                          void *userData )
  143. {
  144.     struct InterruptEntry *ie;
  145.  
  146.     if (ie = tbAllocVecPooled(globalPool, sizeof(struct InterruptEntry))) {
  147.         if (SendDaemon("GetIntList")) {
  148.             while (ReceiveDecodedEntry((UBYTE *)ie, sizeof(struct InterruptEntry))) {
  149.                 callback(ie, userData);
  150.             }
  151.         }
  152.  
  153.         tbFreeVecPooled(globalPool, ie);
  154.     }
  155. }
  156.  
  157. static void IterateList( void (* callback)( struct InterruptEntry *ie, void *userData ),
  158.                          void *userData )
  159. {
  160.     struct MinList tmplist;
  161.     struct InterruptEntry *ie, *_ie;
  162.     ULONG vec;
  163.  
  164.     NewList((struct List *)&tmplist);
  165.  
  166.     Forbid();
  167.  
  168.     for (vec = 0; vec <= 15; vec++) {
  169.         struct IntVector *intvec;
  170.  
  171.         if (intvec = (struct IntVector *)&SysBase->IntVects[vec]) {
  172.             if (ie = AllocVec(sizeof(struct InterruptEntry), MEMF_PUBLIC)) {
  173.                 if (intvec->iv_Node == NULL && intvec->iv_Data != NULL && intvec->iv_Data != (APTR)-1) {
  174.                     struct Interrupt *irq;
  175.                     ULONG servercnt;
  176.  
  177.                     ie->ie_Addr = NULL;
  178.                     _snprintf(ie->ie_Address, sizeof(ie->ie_Address), "$%08lx", intvec);
  179.                     ie->ie_Name[0] = 0x00;
  180.                     if (points2ram((APTR)intvec->iv_Code)) {
  181.                         _snprintf(ie->ie_Code, sizeof(ie->ie_Code), MUIX_PH "$%08lx" MUIX_PT, intvec->iv_Code);
  182.                     } else {
  183.                         _snprintf(ie->ie_Code, sizeof(ie->ie_Code), "$%08lx", intvec->iv_Code);
  184.                     }
  185.                     _snprintf(ie->ie_Data, sizeof(ie->ie_Data), "$%08lx", intvec->iv_Data);
  186.                     _snprintf(ie->ie_Pri, sizeof(ie->ie_Pri), "%4ld", vec);
  187.                     stccpy(ie->ie_Number, intTypeShort[vec], sizeof(ie->ie_Number));
  188.                     stccpy(ie->ie_RealNumber, intTypeShort[vec], sizeof(ie->ie_RealNumber));
  189.                     stccpy(ie->ie_Kind, "Server", sizeof(ie->ie_Kind));
  190.                     stccpy(ie->ie_Type, "SERVER_LIST", sizeof(ie->ie_Type));
  191.                     ie->ie_IntNumber = vec;
  192.  
  193.                     AddTail((struct List *)&tmplist, (struct Node *)ie);
  194.  
  195.                     servercnt = 0;
  196.                     ITERATE_LIST(intvec->iv_Data, struct Interrupt *, irq) {
  197.                         if (ie = AllocVec(sizeof(struct InterruptEntry), MEMF_PUBLIC)) {
  198.                             servercnt++;
  199.  
  200.                             ie->ie_Addr = irq;
  201.                             if (points2ram((APTR)irq->is_Code)) {
  202.                                 _snprintf(ie->ie_Code, sizeof(ie->ie_Code), MUIX_PH "$%08lx" MUIX_PT, irq->is_Code);
  203.                             } else {
  204.                                 _snprintf(ie->ie_Code, sizeof(ie->ie_Code), "$%08lx", irq->is_Code);
  205.                             }
  206.                             _snprintf(ie->ie_Address, sizeof(ie->ie_Address), "$%08lx", irq);
  207.                             stccpy(ie->ie_Name, nonetest(irq->is_Node.ln_Name), sizeof(ie->ie_Name));
  208.                             _snprintf(ie->ie_Pri, sizeof(ie->ie_Pri), "%4ld", irq->is_Node.ln_Pri);
  209.                             _snprintf(ie->ie_Data, sizeof(ie->ie_Data), "$%08lx", irq->is_Data);
  210.                             _snprintf(ie->ie_Number, sizeof(ie->ie_Number), "%ld", servercnt);
  211.                             stccpy(ie->ie_RealNumber, intTypeShort[vec], sizeof(ie->ie_RealNumber));
  212.                             stccpy(ie->ie_Kind, "Server", sizeof(ie->ie_Kind));
  213.                             stccpy(ie->ie_Type, "SERVER_NODE", sizeof(ie->ie_Type));
  214.                             ie->ie_IntNumber = vec;
  215.  
  216.                             AddTail((struct List *)&tmplist, (struct Node *)ie);
  217.                         }
  218.                     }
  219.                 } else {
  220.                     struct Interrupt *irq;
  221.  
  222.                     irq = (struct Interrupt *)intvec->iv_Node;
  223.  
  224.                     if (intvec->iv_Node != NULL && intvec->iv_Code != NULL) {
  225.                         ie->ie_Addr = irq;
  226.                     } else {
  227.                         ie->ie_Addr = NULL;
  228.                     }
  229.  
  230.                     if (points2ram((APTR)intvec->iv_Code)) {
  231.                         _snprintf(ie->ie_Code, sizeof(ie->ie_Code), MUIX_PH "$%08lx" MUIX_PT, intvec->iv_Code);
  232.                     } else {
  233.                         _snprintf(ie->ie_Code, sizeof(ie->ie_Code), "$%08lx", intvec->iv_Code);
  234.                     }
  235.                     _snprintf(ie->ie_Address, sizeof(ie->ie_Address), "$%08lx", intvec);
  236.                     if (irq) {
  237.                         stccpy(ie->ie_Name, nonetest(irq->is_Node.ln_Name), sizeof(ie->ie_Name));
  238.                     } else {
  239.                         stccpy(ie->ie_Name, nonetest(NULL), sizeof(ie->ie_Name));
  240.                     }
  241.                     _snprintf(ie->ie_Pri, sizeof(ie->ie_Pri), "%4ld", vec);
  242.                     _snprintf(ie->ie_Data, sizeof(ie->ie_Data), "$%08lx", intvec->iv_Data);
  243.                     stccpy(ie->ie_Number, intTypeShort[vec], sizeof(ie->ie_Number));
  244.                     stccpy(ie->ie_RealNumber, intTypeShort[vec], sizeof(ie->ie_RealNumber));
  245.                     if (intvec->iv_Data == NULL && intvec->iv_Code == NULL) {
  246.                         stccpy(ie->ie_Kind, "Unused", sizeof(ie->ie_Kind));
  247.                     } else if (intvec->iv_Data == (APTR)-1 && intvec->iv_Code == (APTR)-1) {
  248.                         stccpy(ie->ie_Kind, "Free", sizeof(ie->ie_Kind));
  249.                     } else {
  250.                         stccpy(ie->ie_Kind, "Handler", sizeof(ie->ie_Kind));
  251.                     }
  252.                     stccpy(ie->ie_Type, "HANDLER", sizeof(ie->ie_Type));
  253.                     ie->ie_IntNumber = vec;
  254.  
  255.                     AddTail((struct List *)&tmplist, (struct Node *)ie);
  256.                 }
  257.             }
  258.         }
  259.     }
  260.  
  261.     Permit();
  262.  
  263.     ITERATE_CHANGING_LIST(&tmplist, struct InterruptEntry *, ie, _ie) {
  264.         callback(ie, userData);
  265.         FreeVec(ie);
  266.     }
  267. }
  268.  
  269. static void UpdateCallback( struct InterruptEntry *ie,
  270.                             void *userData )
  271. {
  272.     struct InterruptsCallbackUserData *ud = (struct InterruptsCallbackUserData *)userData;
  273.     struct MUI_NListtree_TreeNode *parent;
  274.     ULONG flags;
  275.     BOOL search_parent;
  276.  
  277.     flags = 0;
  278.     search_parent = FALSE;
  279.     if (stricmp(ie->ie_Type, "HANDLER") == 0) {
  280.         ud->ud_Count++;
  281.     } else if (stricmp(ie->ie_Type, "SERVER_LIST") == 0) {
  282.         flags = TNF_LIST | TNF_OPEN;
  283.         // don't count up, we only count real IRQ entries
  284.     } else if (stricmp(ie->ie_Type, "SERVER_NODE") == 0) {
  285.         ud->ud_Count++;
  286.         search_parent = TRUE;
  287.     }
  288.  
  289.     if (search_parent) {
  290.         parent = (struct MUI_NListtree_TreeNode *)DoMethod(ud->ud_Tree, MUIM_NListtree_FindUserData, MUIV_NListtree_FindUserData_ListNode_Root, ie->ie_RealNumber, MUIV_NListtree_FindUserData_Flag_StartNode);
  291.     } else {
  292.         parent = MUIV_NListtree_Insert_ListNode_Root;
  293.     }
  294.     DoMethod(ud->ud_Tree, MUIM_NListtree_Insert, ie->ie_Name, ie, parent, MUIV_NListtree_Insert_PrevNode_Tail, flags);
  295. }
  296.  
  297. static void PrintCallback( struct InterruptEntry *ie,
  298.                            void *userData )
  299. {
  300.     PrintFOneLine((BPTR)userData, " %s %4s %s %-9.9s  %-20s %-7.7s %s\n", ie->ie_Address, ie->ie_Pri, ie->ie_Data, (ie->ie_Code[0] != '\033') ? ie->ie_Code : ie->ie_Code + 2, ie->ie_RealNumber, ie->ie_Kind, ie->ie_Name);
  301. }
  302.  
  303. static void SendCallback( struct InterruptEntry *ie,
  304.                           void *userData )
  305. {
  306.     SendEncodedEntry((UBYTE *)ie, sizeof(struct InterruptEntry));
  307. }
  308.  
  309. static void FindCallback( struct InterruptEntry *ie,
  310.                           void *userData )
  311. {
  312.     struct InterruptsCallbackUserData *ud = (struct InterruptsCallbackUserData *)userData;
  313.  
  314.     if (stricmp(ud->ud_FindMe, ie->ie_Name) == 0) ud->ud_FoundThis = ie->ie_Addr;
  315. }
  316.  
  317. static void RemoveCallback( struct InterruptEntry *ie,
  318.                             void *userData )
  319. {
  320.     struct InterruptsCallbackUserData *ud = (struct InterruptsCallbackUserData *)userData;
  321.  
  322.     if (stricmp(ie->ie_Type, "SERVER_NODE") == 0 && stricmp(ud->ud_FindMe, ie->ie_Name) == 0) {
  323.         RemIntServer(ie->ie_IntNumber, ie->ie_Addr);
  324.         ud->ud_FoundThis = ie->ie_Addr;
  325.     }
  326. }
  327.  
  328. static ULONG __saveds mNew( struct IClass *cl,
  329.                             Object *obj,
  330.                             struct opSet *msg )
  331. {
  332.     APTR intlist, inttree, inttext, intcount, updateButton, printButton, removeButton, moreButton, exitButton;
  333.  
  334.     if (obj = (Object *)DoSuperNew(cl, obj,
  335.         MUIA_HelpNode, InterruptsText,
  336.         MUIA_Window_ID, MakeID('I','N','T','E'),
  337.         WindowContents, VGroup,
  338.  
  339.             Child, intlist = MyNListtreeObject(&inttree, "BAR,BAR,BAR,BAR P=" MUIX_C ",BAR P=" MUIX_R ",BAR,BAR", &inttree_conhook, &inttree_deshook, &inttree_dsphook, NULL, &inttree_findhook, 1),
  340.             Child, MyBelowListview(&inttext, &intcount),
  341.  
  342.             Child, MyVSpace(4),
  343.  
  344.             Child, HGroup, MUIA_Group_SameSize, TRUE,
  345.                 Child, updateButton = MakeButton(txtUpdate),
  346.                 Child, printButton  = MakeButton(txtPrint),
  347.                 Child, removeButton = MakeButton(txtRemove),
  348.                 Child, moreButton   = MakeButton(txtMore),
  349.                 Child, exitButton   = MakeButton(txtExit),
  350.             End,
  351.         End,
  352.         TAG_MORE, msg->ops_AttrList))
  353.     {
  354.         struct InterruptsWinData *iwd = INST_DATA(cl, obj);
  355.         APTR parent;
  356.  
  357.         iwd->iwd_InterruptTree = inttree;
  358.         iwd->iwd_InterruptText = inttext;
  359.         iwd->iwd_InterruptCount = intcount;
  360.         iwd->iwd_RemoveButton = removeButton;
  361.         iwd->iwd_MoreButton = moreButton;
  362.  
  363.         parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);
  364.  
  365.         set(obj, MUIA_Window_Title, MyGetWindowTitle("INTERRUPTS", iwd->iwd_Title, sizeof(iwd->iwd_Title)));
  366.         set(obj, MUIA_Window_ActiveObject, intlist);
  367.         set(moreButton, MUIA_Disabled, TRUE);
  368.  
  369.         DoMethod(parent,       MUIM_Window_AddChildWindow, obj);
  370.         DoMethod(obj,          MUIM_Notify, MUIA_Window_CloseRequest,   TRUE,           MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
  371.         DoMethod(inttree,      MUIM_Notify, MUIA_NListtree_Active,      MUIV_EveryTime, obj,                     1, MUIM_InterruptsWin_ListChange);
  372.         DoMethod(inttree,      MUIM_Notify, MUIA_NListtree_DoubleClick, MUIV_EveryTime, obj,                     1, MUIM_InterruptsWin_More);
  373.         DoMethod(updateButton, MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_InterruptsWin_Update);
  374.         DoMethod(printButton,  MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_InterruptsWin_Print);
  375.         DoMethod(removeButton, MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_InterruptsWin_Remove);
  376.         DoMethod(moreButton,   MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_InterruptsWin_More);
  377.         DoMethod(exitButton,   MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     3, MUIM_Set, MUIA_Window_CloseRequest, TRUE);
  378.     }
  379.  
  380.     return (ULONG)obj;
  381. }
  382.  
  383. static ULONG __saveds mDispose( struct IClass *cl,
  384.                                 Object *obj,
  385.                                 struct opSet *msg )
  386. {
  387.     struct InterruptsWinData *iwd = INST_DATA(cl, obj);
  388.  
  389.     set(obj, MUIA_Window_Open, FALSE);
  390.     DoMethod(iwd->iwd_InterruptTree, MUIM_NListtree_Clear, NULL, 0);
  391.  
  392.     return (DoSuperMethodA(cl, obj, msg));
  393. }
  394.  
  395. static ULONG __saveds mUpdate( struct IClass *cl,
  396.                                Object *obj,
  397.                                Msg msg )
  398. {
  399.     struct InterruptsWinData *iwd = INST_DATA(cl, obj);
  400.     struct InterruptsCallbackUserData ud;
  401.  
  402.     ApplicationSleep(TRUE);
  403.     set(iwd->iwd_InterruptTree, MUIA_NListtree_Quiet, TRUE);
  404.     DoMethod(iwd->iwd_InterruptTree, MUIM_NListtree_Clear, NULL, 0);
  405.  
  406.     ud.ud_Tree = iwd->iwd_InterruptTree;
  407.     ud.ud_Count = 0;
  408.  
  409.     if (clientstate) {
  410.         ReceiveList(UpdateCallback, &ud);
  411.     } else {
  412.         IterateList(UpdateCallback, &ud);
  413.     }
  414.  
  415.     SetCountText(iwd->iwd_InterruptCount, ud.ud_Count);
  416.     MySetContents(iwd->iwd_InterruptText, "");
  417.  
  418.     set(iwd->iwd_InterruptTree, MUIA_NListtree_Quiet, FALSE);
  419.     set(iwd->iwd_InterruptTree, MUIA_NListtree_Active, MUIV_NListtree_Active_Off);
  420.     set(iwd->iwd_RemoveButton, MUIA_Disabled, TRUE);
  421.     set(iwd->iwd_MoreButton, MUIA_Disabled, TRUE);
  422.     ApplicationSleep(FALSE);
  423.  
  424.     return 0;
  425. }
  426.  
  427. static ULONG __saveds mPrint( struct IClass *cl,
  428.                               Object *obj,
  429.                               Msg msg )
  430. {
  431.     PrintInterrupts(NULL);
  432.  
  433.     return 0;
  434. }
  435.  
  436. static ULONG __saveds mRemove( struct IClass *cl,
  437.                                Object *obj,
  438.                                Msg msg )
  439. {
  440.     struct InterruptsWinData *iwd = INST_DATA(cl, obj);
  441.     struct MUI_NListtree_TreeNode *tn;
  442.  
  443.     if (tn = GetActiveTreeNode(iwd->iwd_InterruptTree)) {
  444.         struct InterruptEntry *ie = (struct InterruptEntry *)tn->tn_User;
  445.  
  446.         if (stricmp(ie->ie_Type, "HANDLER") == 0) {
  447.             MyRequest(msgErrorContinue, msgCantRemoveInterruptHandler);
  448.         } else {
  449.             if (MyRequest(msgYesNo, msgWantToRemoveInterrupt, ie->ie_Name)) {
  450.                 MyDoCommand("RemoveInterrupt \"%s\"", ie->ie_Name);
  451.                 DoMethod(obj, MUIM_InterruptsWin_Update);
  452.             }
  453.         }
  454.     }
  455.  
  456.     return 0;
  457. }
  458.  
  459. static ULONG __saveds mMore( struct IClass *cl,
  460.                              Object *obj,
  461.                              Msg msg )
  462. {
  463.     struct InterruptsWinData *iwd = INST_DATA(cl, obj);
  464.     struct MUI_NListtree_TreeNode *tn;
  465.  
  466.     if (tn = GetActiveTreeNode(iwd->iwd_InterruptTree)) {
  467.         struct InterruptEntry *ie = (struct InterruptEntry *)tn->tn_User;
  468.  
  469.         if ((stricmp(ie->ie_Type, "HANDLER") == 0 && ie->ie_Addr != NULL) || stricmp(ie->ie_Type, "SERVER_NODE") == 0) {
  470.             APTR detailWin;
  471.  
  472.             if (detailWin = InterruptsDetailWindowObject,
  473.                     MUIA_Window_ParentWindow, obj,
  474.                 End) {
  475.                 set(detailWin, MUIA_InterruptsDetailWin_Interrupt, ie);
  476.                 set(detailWin, MUIA_Window_Open, TRUE);
  477.             }
  478.         }
  479.     }
  480.  
  481.     return 0;
  482. }
  483.  
  484. static ULONG __saveds mListChange( struct IClass *cl,
  485.                                    Object *obj,
  486.                                    Msg msg )
  487. {
  488.     struct InterruptsWinData *iwd = INST_DATA(cl, obj);
  489.     struct MUI_NListtree_TreeNode *tn;
  490.  
  491.     if (tn = GetActiveTreeNode(iwd->iwd_InterruptTree)) {
  492.         struct InterruptEntry *ie = (struct InterruptEntry *)tn->tn_User;
  493.  
  494.         if (stricmp(ie->ie_Type, "HANDLER") == 0 && ie->ie_Addr != NULL) {
  495.             MySetContents(iwd->iwd_InterruptText, "%s \"%s\"", ie->ie_Address, ie->ie_Name);
  496.             set(iwd->iwd_RemoveButton, MUIA_Disabled, TRUE);
  497.             if (!clientstate) set(iwd->iwd_MoreButton, MUIA_Disabled, FALSE);
  498.         } else if (stricmp(ie->ie_Type, "SERVER_LIST") == 0) {
  499.             MySetContents(iwd->iwd_InterruptText, "");
  500.             set(iwd->iwd_RemoveButton, MUIA_Disabled, TRUE);
  501.             if (!clientstate) set(iwd->iwd_MoreButton, MUIA_Disabled, TRUE);
  502.         } else if (stricmp(ie->ie_Type, "SERVER_NODE") == 0) {
  503.             MySetContents(iwd->iwd_InterruptText, "%s \"%s\"", ie->ie_Address, ie->ie_Name);
  504.             set(iwd->iwd_RemoveButton, MUIA_Disabled, FALSE);
  505.             if (!clientstate) set(iwd->iwd_MoreButton, MUIA_Disabled, FALSE);
  506.         } else {
  507.             MySetContents(iwd->iwd_InterruptText, "");
  508.             set(iwd->iwd_RemoveButton, MUIA_Disabled, TRUE);
  509.             set(iwd->iwd_MoreButton, MUIA_Disabled, TRUE);
  510.         }
  511.     }
  512.  
  513.     return 0;
  514. }
  515.  
  516. ULONG __asm __saveds InterruptsWinDispatcher( register __a0 struct IClass *cl,
  517.                                           register __a2 Object *obj,
  518.                                           register __a1 Msg msg )
  519. {
  520.     switch (msg->MethodID) {
  521.         case OM_NEW:                        return (mNew(cl, obj, (APTR)msg));
  522.         case OM_DISPOSE:                    return (mDispose(cl, obj, (APTR)msg));
  523.         case MUIM_InterruptsWin_Update:     return (mUpdate(cl, obj, (APTR)msg));
  524.         case MUIM_InterruptsWin_Print:      return (mPrint(cl, obj, (APTR)msg));
  525.         case MUIM_InterruptsWin_Remove:     return (mRemove(cl, obj, (APTR)msg));
  526.         case MUIM_InterruptsWin_More:       return (mMore(cl, obj, (APTR)msg));
  527.         case MUIM_InterruptsWin_ListChange: return (mListChange(cl, obj, (APTR)msg));
  528.     }
  529.  
  530.     return (DoSuperMethodA(cl, obj, msg));
  531. }
  532.  
  533. void PrintInterrupts( char *filename )
  534. {
  535.     BPTR handle;
  536.  
  537.     if (handle = HandlePrintStart(filename)) {
  538.         PrintFOneLine(handle, "\n  Address   Pri   Data      Code      NUM                 IntType Name\n\n");
  539.         IterateList(PrintCallback, (void *)handle);
  540.     }
  541.  
  542.     HandlePrintStop();
  543. }
  544.  
  545. void SendIntList( void )
  546. {
  547.     IterateList(SendCallback, NULL);
  548. }
  549.  
  550. struct Interrupt *FindInterrupt( UBYTE *name )
  551. {
  552.     struct InterruptsCallbackUserData ud;
  553.  
  554.     ud.ud_FindMe = name;
  555.     ud.ud_FoundThis = NULL;
  556.  
  557.     IterateList(FindCallback, &ud);
  558.  
  559.     return ud.ud_FoundThis;
  560. }
  561.  
  562. struct Interrupt *RemoveInterrupt( UBYTE *name )
  563. {
  564.     struct InterruptsCallbackUserData ud;
  565.  
  566.     ud.ud_FindMe = name;
  567.     ud.ud_FoundThis = NULL;
  568.  
  569.     IterateList(RemoveCallback, &ud);
  570.  
  571.     return ud.ud_FoundThis;
  572. }
  573.  
  574.